import urllib
import datetime
import time
import MSData
from MSLogger import logDebug, logWarn, logError, logInfo
from pdb import set_trace

def now():
    return datetime.datetime.fromtimestamp(time.time())
def nowPastTenMinutes():
    return now() - datetime.timedelta(0, 600)
#exceptionally safe read all strings from the url or return None
def readURL(URL):
    try:
        f = urllib.urlopen('%s' % (URL))
        d = f.readlines()
        if len(d) == 0:
            logDebug('No any event on %s' % (URL))
            return None
        logDebug('Got %d events on %s' % (len(d), URL))
        return d
    except (Exception), err:
        logError('connection failed to %s' % (URL))
        return None

def readMSURL(Request, Skey, Begin, End):
    return readURL('http://api.car-online.ru/do?data=%s&skey=%s&begin=%s&end=%s&filter=1' % (Request, Skey, Begin, End))

def getBeginEnd(Object):
    begin = None
    if Object.lastEvent != None:
        begin = Object.lastEvent.eventReceiveTime
    else:
        begin = nowPastTenMinutes()
    end = now()
    return (begin, end)

def parseEventLine(EventLine, EventId):
    s = EventLine.split('/>')[0]
    s = s.split('<')[1]
    s = s.split(' ')
    e = {}
    for prop in s[1:len(s)]:
        prop = prop.split('=')
        e[prop[0]] = prop[1].replace('"', '')
    e['eventInternalId'] = EventId
    return e

def readStaticPGSMEvents(Object, EventId):
    timeRange = getBeginEnd(Object)
    b = str(timeRange[0].strftime(MSData.TIME_FORMAT_MAGIC))
    e = str(timeRange[1].strftime(MSData.TIME_FORMAT_MAGIC))
    data = readMSURL('events', Object.objectSkey, b, e)

    #TBD at this check we should also check if an alarm on silence specified for an object
    if data == None and Object.lastEvent != None and Object.offlineCritical != None and not Object.offlineState and (now() - Object.lastEvent.eventReceiveTime > Object.offlineCritical):
        try:
            e = MSData.MSEvent()
            e.hasStatic = True
            e.objectId = Object.objectId
            e.contactIdType = '3551'
            e.eventId = EventId
            Object.offlineState = True
            Object.processEvent(e)
            return EventId + 1
        except (Exception), err:
            logError('unable to generate offline critical event for and object(%s)' % (str(Object.objectId)))
    if data == None:
        return EventId
    if data != None and Object.offlineState:
        try:
            e = MSData.MSEvent()
            e.hasStatic = True
            e.objectId = Object.objectId
            e.contactIdType = '3553'
            e.eventId = EventId
            Object.offlineState = False
            Object.processEvent(e)
        except (Exception), err:
            logError('unable to generate offline critical event for and object(%s)' % (str(Object.objectId)))

    eid = EventId
    processed = 0
    for s in data:
        try:
            EventId = eid
            eHash = parseEventLine(s, eid)        
            e = MSData.MSEvent()
            e.objectId = Object.objectId
            e.fromPGSM(eHash)
            if e.eventGenerateTime < timeRange[0]:
                raise 'ERROR: requested event time range from %s to %s received event of %s' % (str(b), str(e), str(e.eventGenerateTime))
            Object.processEvent(e)
            eid += 1
            processed += 1

        except (Exception), err:
            logDebug('PGSM: unable to parse: %s with error: %s' % (str(s), str(err)))
            eid = EventId
            continue
    logInfo('processed %d pgsm events for %d object' % (processed, int(Object.objectId)))
    return eid

def readStaticContactIdEvents(Object, EventId):
    timeRange = getBeginEnd(Object)
    b = str(timeRange[0].strftime(MSData.TIME_FORMAT_MAGIC))
    e = str(timeRange[1].strftime(MSData.TIME_FORMAT_MAGIC))
    data = readMSURL('contactId', Object.objectSkey, b, e)

    if data == None:
        return EventId

    eid = EventId
    processed = 0
    for s in data:
        try:
            EventId = eid
            eHash = parseEventLine(s, eid)        
            e = MSData.MSEvent()
            e.fromContactId(eHash)
            if e.eventGenerateTime < timeRange[0]:
                raise 'ERROR: requested event time range from %s to %s received event of %s' % (str(b), str(e), str(e.eventGenerateTime))
            Object.processEvent(e)
            eid += 1
            processed += 1

        except (Exception), err:
            logDebug('ContactId: unable to parse: %s with error: %s' % (str(s), str(err)))
            eid = EventId
            continue
    logInfo('processed %d contactid events for %d object' % (processed, int(Object.objectId)))
    return eid

def readMobileEvents(Object, EventId):
    timeRange = getBeginEnd(Object)
    b = str(timeRange[0].strftime(MSData.TIME_FORMAT_MAGIC))
    e = str(timeRange[1].strftime(MSData.TIME_FORMAT_MAGIC))
    data = readMSURL('gpsPoints', Object.objectSkey, b, e)

    if data == None:
        return EventId

    eid = EventId
    processed = 0
    for s in data:
        try:
            EventId = eid
            eHash = parseEventLine(s, EventId)        
            e = MSData.MSEvent()
            e.objectId = Object.objectId
            e.fromGPSPoint(eHash)
            if e.eventGenerateTime < timeRange[0]:
                continue
            Object.processEvent(e)
            eid += 1
            processed += 1

        except (Exception), err:
            logDebug('GPS: unable to parse: %s with error: %s' % (str(s), str(err)))
            eid = EventId
            continue
    logInfo('processed %d mobile events for %d object' % (processed, int(Object.objectId)))
    return eid

